#include "Cloth.h"
#include "Engine.h"
#include "Inventory.h"
#include "StageManager.h"
#include "ObjectManager.h"

const char Cloth::className[] = "Cloth";

#define method(class, name) {#name, &class::name}

Lunar<Cloth>::RegType Cloth::methods[] = {
	method(Cloth, load),
	method(Cloth, setImg),
	method(Cloth, setClothID),
};

Cloth::Cloth() {
	m_bremove = false;
	m_bunlocked = false;

	ObjectManager::getInstance().addCloth(this);
}

Cloth::Cloth(lua_State* L) {
	m_bremove = false;
	m_bunlocked = false;

	ObjectManager::getInstance().addCloth(this);
}

Cloth::~Cloth() {
}

void Cloth::update() {
	if(m_bremove) {
		ObjectManager::getInstance().removeCloth(m_iclothID);
		StageManager::getInstance().getRootNode()->removeChild(m_ptransform);
		m_bremove = false;
	}
	else if(m_bunlocked) {
		m_ptransform->setNodeMask(1);
		m_bunlocked = false;
	}
}

void Cloth::init() {
}

int Cloth::load(lua_State* L) {
	// Read cloth position
	float x,y,z;
	std::string modelFile = "../data/mesh/";

	int nbArgs = lua_gettop(L);
	if (nbArgs == 4 && lua_isnumber(L,1) && lua_isnumber(L,2) && lua_isnumber(L,3) && lua_isstring(L,4)) {
		x = lua_tonumber(L,1);
		y = lua_tonumber(L,2);
		z = lua_tonumber(L,3);
		modelFile += lua_tostring(L,4);
	}
	else {
		std::cerr << "Cloth loading : wrong parameters" << std::endl;
		return 0;
	}

	// Load cloth model
	m_ptransform = new osg::PositionAttitudeTransform;
	osg::Node* cloth = osgDB::readNodeFile(modelFile);

	m_ptransform->addChild(cloth);
	m_ptransform->setPosition(osg::Vec3(x, y, z));

	// Declare instance of class to record state of keyboard
	m_pkeyState = new KeyboardState();

	// Set up the tank update callback
	//  pass the constructor a pointer to our tank input device state
	//  that we declared above.
	m_ptransform->setUpdateCallback(new ClothActionCallback(m_pkeyState, this));

	// The constructor for our event handler also gets a pointer to
	//   our tank input device state instance
	KeyboardEventHandler* clothEventHandler = new KeyboardEventHandler(m_pkeyState);

	// Add our event handler to the list
	Engine::getInstance().getViewer().addEventHandler(clothEventHandler);

	StageManager::getInstance().getRootNode()->addChild(m_ptransform);
	m_ptransform->setNodeMask(0);

	return 0;
}

int Cloth::setImg(lua_State* L) {
	m_simgFile = "../data/image/";
	int nbArgs = lua_gettop(L);
	if (nbArgs == 1 && lua_isstring(L,1)) {
		m_simgFile += lua_tostring(L,1);
		return 0;
	}
	return -1;
}

int Cloth::setClothID(lua_State* L) {
	int nbArgs = lua_gettop(L);
	if (nbArgs == 1 && lua_isnumber(L,1)) {
		m_iclothID = lua_tonumber(L,1);
		return 0;
	}
	return -1;
}

void ClothActionCallback::operator()(osg::Node* node, osg::NodeVisitor* nv) {
	osg::PositionAttitudeTransform* pat = dynamic_cast<osg::PositionAttitudeTransform*> (node);
	if(pat) {
		if ((m_pkeyState->m_key == osgGA::GUIEventAdapter::KEY_Space)&&(m_pkeyState->m_keydown)) {
			osg::Vec3d pos = pat->getPosition();
			osg::Vec3d playerPos = StageManager::getInstance().getCurrentStage()->getPlayer()->getPosition();
			float dist = (pos-playerPos).length();

			if(dist < 3.) {
				m_pkeyState->m_keydown = false;

				StageManager::getInstance().getCurrentStage()->getPlayer()->getInventory()->addCloth(m_pcloth->getClothID(), m_pcloth->getImg());
				m_pcloth->setRemove(true);
				m_pcloth->getTransform()->removeUpdateCallback(this);
				
				return;
			}
		}
	}
	traverse(node, nv); 
}